home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™ 1987-1994 / MacHack™ '92 / Hacks ’92 / tclObjNameƒ / tclObjName.c < prev    next >
Encoding:
Text File  |  1992-06-17  |  10.7 KB  |  391 lines  |  [TEXT/MPS ]

  1. /*
  2. From: bhamlin@netcom.com (Brian Hamlin)
  3. To: tcl-talk@brown.edu, shayer@applelink.apple.com
  4. Subject:  debugging DCMD srcs
  5.  
  6.     B. Marshall Hamlin
  7.     Constructor, Noesis Sfwr Construction
  8.     
  9.     6300 Leona St
  10.     Oakland, CA  94605-1228
  11.  
  12. All:
  13.  
  14.   Have you ever been frustrated in debugging TCL situations, breaking
  15. on something like CView::Activate() 27 times, and on the 28th low-and-
  16. behold there is your bug, but the debugger tells you the object is a,
  17. you guessed it, CView!  The stack crawl is ok, if you can see past some
  18. factorial number of DispatchClicks, DoCommands and the like. What *I* 
  19. really wanted was the name of my !@^%#$& object !
  20.  
  21.   So here it is: a DCMD that gives the name of an object, passed the
  22. object's *actual* address in the heap (when the debugger says 
  23. struct 0x0112345)
  24.  
  25.   NOTE: executing Debugger macro __cn(this) shows the current 
  26.   object's name in the src level debugger (!)
  27.  
  28. */
  29.  
  30. /*
  31.   tclObjName  DCMD
  32.   
  33.   USAGE:
  34.   
  35.     pass in the addr of an object on the heap and this dcmd returns 
  36.   the object's class name.  A5 must be current.
  37.  
  38.     pass in no address and this DCMD looks through the application
  39.   heap for possible tcl objects and writes a list to output.
  40.  
  41.     TCL Library code for class_name(). Given the short in the first two 
  42.   bytes of the object handle, return the address of the class name in D0.
  43.  
  44.     MOVEA   4(A7),A0    ; get object ID
  45.     ADDA.L  A5,A0       ; find ptr at ID(A5)
  46.     MOVEQ   #1,D0       ;
  47.     ADD     (A0)+,D0    ; off2 = *p + 1
  48.     LSL     #2,D0       ; off2 *= 4
  49.     ADDA.W  D0,A0       ; find obj record
  50.     MOVEQ   #16,D0      ; name at offset 0x10
  51.     ADD.L   A0,D0       ; return name ptr
  52.     RTS  
  53.  
  54.  
  55.   FIX:
  56.   
  57.     -detect non ascii chars in potential class-name
  58.     -show all _still_ questionable blocks with a '?'
  59.     -find bug in globals !
  60.     -allow a string to be passed as a match patt for class names
  61.  
  62.  
  63.   CREATED:                                              28apr92  bh
  64.  
  65.   Copyright 1992, Noesis
  66.   
  67.   Permission to use, copy, modify, and distribute this software and its
  68.   documentation for any purpose and without fee is hereby granted, provided
  69.   that the above copyright notice appear in all copies and that both that
  70.   copyright notice and this permission notice appear in supporting
  71.   documentation.  This software is provided "as is" without express or
  72.   implied warranty.
  73.  
  74. */
  75.  
  76.                                             //  B E G I N   L I S T I N G
  77. // ***************************************************************************
  78.  
  79. #include <Types.h>
  80. #include "dcmd.h"
  81.  
  82. #define tclBadAddrM(ADDR) (ADDR<*(long*)0x2AA || ADDR>*(long*)0x130)
  83.  
  84. //***************************************************************************
  85.                                            //  F O R W A R D
  86. pascal void   doObjectMap(void);
  87. Boolean       tclBadAddr( long addr);
  88. void          doFindObject( long addr);
  89. pascal void ObjectSearch(long blockAddress, long blockLength, long addrOfMasterPtr, short blockType, Boolean locked, Boolean purgeable, Boolean resource);
  90.  
  91.  
  92.  
  93. //**************************************************************************
  94.                                            //  S T A T I C
  95. static long gObjCnt;
  96. static unsigned long gObjSize;
  97.  
  98. static char gMatchChars[ 34];
  99.  
  100.  
  101. /***************************************************************************
  102.   CommandEntry
  103. ***************************************************************************/
  104. pascal void CommandEntry (dcmdBlock* paramPtr)
  105. {
  106.   long            address;
  107.   short           ch;
  108.   Boolean         ok;
  109.   char              c;
  110.  
  111.  
  112.   switch (paramPtr->request) {
  113.   
  114.     case dcmdInit:
  115.       break;
  116.  
  117.     case dcmdHelp:
  118.       dcmdDrawLine ("\ptclObjName objAddr");
  119.       dcmdDrawLine ("\p   Display class name of a TCL object, bh 19jun92");
  120.       break;
  121.  
  122.     case dcmdDoIt:
  123.     
  124.       gObjCnt = 0;
  125.       gObjSize = 0;
  126.  
  127.       dcmdSwapWorlds();
  128.       if ( paramPtr->registerFile[A5Register] != *(long*)0x904){
  129.         dcmdDrawLine ("\p#tclObjName - A5 world not current");
  130.         return;
  131.       }
  132.     
  133.       // *******************************************************
  134.       // No Params - do a heap map 
  135.       
  136.       if ( (c=dcmdPeekAtNextChar()) == '\n') {
  137.           doObjectMap();
  138.         return;
  139.       }
  140.       
  141.       // *******************************************************
  142.       // Numeric Param - find an address
  143.       
  144.       if ( isdigit(c) ) {
  145.         ch = dcmdGetNextExpression (&address, &ok);
  146.         if (!ok) {
  147.           dcmdDrawLine ("\p#tclObjName - Syntax error");
  148.           return;
  149.         }
  150.         doFindObject( address);
  151.         return;
  152.       }
  153.       
  154.       // *******************************************************
  155.       // Alpha Param - Match a string in Object Name
  156.       
  157.             
  158.       break;
  159.   }
  160.  
  161.  
  162. /***************************************************************************
  163.   tclBadAddr
  164. ***************************************************************************/
  165. Boolean tclBadAddr( long addr)
  166. {
  167.     return (addr<*(long*)0x2AA || addr>*(long*)0x130);
  168. }
  169.  
  170.  
  171. /***************************************************************************
  172.   doFindObject
  173. ***************************************************************************/
  174. void doFindObject( long addr)
  175. {
  176.    unsigned long   p1, p2;
  177.  
  178.   // ******************************************************************
  179.   // Find a single Object's name 
  180.  
  181.   if ( !tclBadAddr( addr)) {
  182.     dcmdDrawLine ("\p#tclObjName - objAddr not in application heap!");
  183.     return;
  184.   }
  185.  
  186.   p1 = *(short*)addr + *(long*)0x904;
  187.   p2 = (*(short*)p1++ + 1)<<2;
  188.   p2 += p1;
  189.   PutCStr( (char*)p2+16);        PutLine();
  190.  
  191.   //dcmdDrawLine( (unsigned char*)((char*)p2+16));  // really a c string
  192.   dcmdDrawLine( "\p*** tclObjName ***");
  193. }
  194.  
  195.  
  196. /***************************************************************************
  197.   ObjectSearch
  198. ***************************************************************************/
  199. pascal void 
  200. ObjectSearch(long blockAddress, long blockLength, long addrOfMasterPtr,
  201.              short blockType, Boolean locked, Boolean purgeable, Boolean resource)
  202. {
  203.     unsigned long   p1, p2;
  204.     char            *s;
  205.     short            cnt, c;
  206.  
  207.     if (blockType != relocatableBlock)
  208.         return;
  209.     //if ( *(short*)blockAddress > 0)
  210.     //    return;
  211.  
  212.     p1 = *(short*)blockAddress + *(long*)0x904;
  213.     //if ( tclBadAddrM( p1)) { PutLine(); return;}
  214.     p2 = (*(short*)p1++ + 1)<<2;
  215.     p2 += p1;
  216.     //if ( tclBadAddr( p2)) { PutLine();  return;}
  217.     s = (char*)p2+16+1;        // what's with the 1 ?
  218.     
  219.     cnt = strlen(s);
  220.     if ( *s < 'A' || *s > 'Z' || cnt < 3 ) { return;}
  221.     for ( c=0;c<cnt;c++)
  222.         if ( !isalpha( s[c]))
  223.             return;
  224.  
  225.     PutChar( (locked)?('L'):(' '));
  226.     PutChar( (blockLength>0x400)?('?'):(' '));
  227.  
  228.     PutCStrTruncTo( s, 32);
  229.     PutSpacesTo( 35);
  230.     //PutUHexZTo( blockLength, 0, 42); 
  231.     PutUHexZ( blockLength, 8);
  232.     PutSpacesTo( 46);
  233.     PutUHexZ( blockAddress, 8);
  234.     PutLine();
  235.  
  236.     gObjCnt++;
  237.     gObjSize += blockLength;
  238.  
  239.     // fake refs section
  240.     if (0) {
  241.         long    l;  Boolean b;
  242.         
  243.         l = blockAddress; l = blockLength; l = addrOfMasterPtr; l = blockType;
  244.         b = locked; b = purgeable; b = resource;
  245.     }
  246.     
  247.     return;
  248. }
  249.  
  250. /***************************************************************************
  251.   doObjectMap
  252. ***************************************************************************/
  253. pascal void doObjectMap()
  254. {
  255.  
  256.     dcmdDrawLine((char*)0x910);
  257.     dcmdDrawLine("\p");
  258.  
  259. //                             1         2         3         4         5         6         7
  260. //                    01234567890123456789012345678901234567890123456789012345678901234567890
  261.     dcmdDrawLine("\p  Object Name                      Size       Addr");
  262.     dcmdDrawLine("\p------------------------------------------------------");
  263.  
  264.     dcmdForAllHeapBlocks( ObjectSearch);
  265.     dcmdDrawLine("\p------------------------------------------------------");
  266.  
  267.     if ( !gObjCnt) {
  268.         dcmdDrawLine("\pNo objects found - Are we really in Kansas, Toto ?");
  269.         dcmdDrawLine("\p");
  270.         return;
  271.     } 
  272.     PutCStr( "Heap Objects found: ");
  273.     PutUDec( gObjCnt);
  274.         PutLine();
  275.     PutCStr( "Heap Objects sizes: ");
  276.     PutUDec( gObjSize);
  277.         PutLine();
  278.     PutCStr( "Total heap size:");
  279.     PutUDec( *(long*)0x130 - *(long*)0x2AA);
  280.         PutLine();
  281.  
  282. }
  283.  
  284.  
  285. // ***************************************************************************
  286. /*                                                        B  U  I  L  D
  287. [
  288.     #getfilename
  289.  
  290.     set dcmdLib 'HD_80:MacsBug 6.2.2:dcmds:dcmd Libraries:'
  291.     set srcDir 'Srcs Shuttle:tclObjNameƒ:'
  292.     
  293.     #set dcmdLib Alliance:MacsBugƒ:dcmdƒ:
  294.     #set srcDir Alliance:Telecom:Netcomƒ:tcl-talk:
  295.  
  296.     #directory {dcmdLib}
  297.     #  C put.c -b
  298.  
  299.     directory "{srcDir}"
  300.  
  301.       C tclObjName.c -b
  302.     Link "{dcmdLib}"dcmdGlue.a.o "{dcmdLib}"put.c.o ∂
  303.             tclObjName.c.o "{dcmdLib}"DRuntime.o ∂
  304.             "{CLibraries}"StdCLib.o "{Libraries}"Interface.o -o tclObjName 
  305.     "{dcmdLib}"BuildDcmd tclObjName 3200
  306.     
  307.     #Rez -ov -a -o 'Alliance:Systemƒ:TMON Folder:HG dcmds & templates'∂
  308.     # tclObjName
  309.     'Alliance:Tools:ResEdit 2.1.1$cs' 'Alliance:Systemƒ:TMON Folder:HG dcmds & templates' tclObjName
  310.  
  311. ]
  312.     
  313.     {dcmdLib}TestDcmd
  314.     
  315.     'Alliance:Tools:ResEdit 2.1.1$cs' {dcmdLib}"Debugger Prefs" tclObjName
  316.  
  317.     dumpobj {Libraries}Interface.o
  318.     dumpobj {CLibraries}StdCLib.o
  319.     set
  320.  
  321.  
  322. -----------------------------------------------------------------------------
  323.     DCMD Put Library
  324.         Copyright © 1988 Apple Computer, Inc.  All rights reserved.
  325. -----------------------------------------------------------------------------
  326.             
  327. o PutLine()
  328.     Write Put Library line buffer to output
  329.  
  330. o PutChar(char c)
  331.     Add 1 char to the line buffer
  332.  
  333. o PutSpace()
  334.     Add 1 space to the line buffer
  335.  
  336. o PutSpacesTo(int pos)
  337.     Add spaces to a position in the line buffer. Tab.
  338.  
  339. o PutBytesTruncTo(const char* s, int len, int pos)
  340.     Put string, ending at a line buffer position. Truncate or pad.
  341.  
  342. o PutBytesTo(const char* s, int len, int pos)
  343.     Put string, writing past position if necessary or pad.
  344.  
  345. o PutCStrTo(const char* s, int pos)
  346.     Write C String to line buffer. Uses PutBytesTo().
  347.  
  348. o PutCStrTruncTo(const char* s, int pos)
  349.     Write string, truncate of necessary. Uses PutBytesTruncTo().
  350.  
  351. o PutCStr(const char* s)
  352.     Write C String to line buffer, never pad.
  353.  
  354. o PutPStrTruncTo(const char* s, int pos)
  355.     Write pascal string, uses PutBytesTruncTo().
  356.  
  357. o PutPStrTo(const char* s, int pos)
  358.     Write pascal string, uses PutBytesTo().
  359.  
  360. o PutPStr(const char* s)
  361.     Write pascal string, uses PutBytesTo().
  362.  
  363. o PutUHexZTo(unsigned long i, int ndig, int pos)
  364.     Write unsigned hex string ending at position.
  365.     ndig -> number of digits in string
  366.     Bug: no check for linepos > pos
  367.  
  368. o PutUHexZ(unsigned long i, int nz)
  369.     Write unsigned hex string, uses PutUHexZTo()
  370.     nz -> number of digits in string
  371.  
  372. o PutUHexWord(unsigned long i)
  373.     Write 2 bytes as Unsigned Hex, uses PutUHexZTo().
  374.  
  375. o PutUDecTo(unsigned long i, int pos)
  376.     Write decimal string ending at position.
  377.     Bug: no check for linepos > pos
  378.  
  379. o PutUDec(unsigned long i)
  380.     Write decimal string, uses PutUDecTo().
  381.  
  382. o PutOSType(unsigned long typ)
  383.     Write 4 bytes as chars, no conversion. Uses PutChar().
  384.     
  385. */
  386. // ***************************************************************************
  387.                                            //  E N D  O F  L I S T I N G
  388.  
  389.  
  390.